#include <iostream>

#include <string.h>
#include <math.h>
#include <pthread.h>
#include <semaphore.h>

#include "SynchroQueue.h"
#include "DftShowDbe.h"
#include "PaReader.h"
#include "data.h"


using namespace std;


void *thrConsumeRawAudioData(void *arg)
{
    my_pa_data *paData = (my_pa_data *) arg;
    SynchroQueue *queRaw = paData->queRawAudioData;
    SynchroQueue *queOut = paData->queDftMod;

    while (!queRaw->getSourceIsFinished() || queRaw->getSize() > 0)
    {
        void *pRawData = queRaw->get();
        if (pRawData == NULL)
        {
            usleep(100);
            continue;
        }

        void *pDftMod = paData->dft->calculate_DFT_Mod(pRawData);
        //void *pDftMod = paData->dft->calculate_DCT_Mod(pRawData);

        void *pOverflowData = queOut->addAndGetIfFull(pDftMod);
        if (pOverflowData != NULL)
        {
            cout << "paData->queDftMod->addAndGetIfFull overflow " << queOut->getSize() << endl;
            free(pOverflowData);
        }

        free(pRawData);
    }

    queOut->setSourceIsFinished();
    return NULL;
}


int main()
{
    cout << "Start..." << endl;
    my_pa_data *paData = (my_pa_data *) calloc(sizeof(my_pa_data), 1);

    cout << "Init paData" << endl;
    paData->DftMsecs = 50;
    paData->queRawAudioData = new SynchroQueue(10000 / 50);
    paData->queDftMod = new SynchroQueue(10000 / 50);

    cout << "Fork thrVisualizeDftData" << endl;
    pthread_t pthrVisual;
    pthread_create(&pthrVisual, NULL, thr_show_dft_results_dbe, (void*) paData);
    cout << "thrVisualizeDftData: " << pthrVisual << endl;

    cout << "Fork thrConsumeRawAudioData" << endl;
    pthread_t pthrRawData;
    pthread_create(&pthrRawData, NULL, thrConsumeRawAudioData, (void*) paData);
    cout << "thrConsumeRawAudioData: " << pthrRawData << endl;

    cout << "Fork thrPaReader" << endl;
    pthread_t pthrPaReader;
    pthread_create(&pthrPaReader, NULL, thr_read_from_pa, (void*) paData);
    cout << "thrPaReader: " << pthrPaReader << endl;

    while (true)
    {
        sleep(1);
        cout << "que " << paData->queRawAudioData->getSize() << " -> " << paData->queDftMod->getSize() << endl;
    }

    cout << "End ?" << endl;
    return 0;
}
